home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / AX25DUMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-18  |  4.6 KB  |  189 lines

  1. /* AX25 header tracing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. /* Mods by PA0GRI */
  5. #include "global.h"
  6. #ifdef AX25
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9. #include "trace.h"
  10.  
  11. #if !defined(_lint)
  12. static char rcsid[] OPTIONAL = "$Id: ax25dump.c,v 1.12 1997/08/19 01:19:22 root Exp root $";
  13. #endif
  14.  
  15. static const char *decode_the_type (int16 type);
  16.  
  17.  
  18. /* Dump an AX.25 packet header */
  19. void
  20. ax25_dump (fp, bpp, check)
  21. FILE *fp;
  22. struct mbuf **bpp;
  23. int check OPTIONAL;        /* Not used */
  24. {
  25. char tmp[AXBUF];
  26. char frmr[3];
  27. int control, pid, seg;
  28. int16 type;
  29. int unsegmented;
  30. struct ax25 hdr;
  31. char *hp;
  32.  
  33.     traceprintf (fp, "AX25: ");
  34.     /* Extract the address header */
  35.     if (ntohax25 (&hdr, bpp) < 0) {
  36.         /* Something wrong with the header */
  37.         traceprintf (fp, " bad header!\n");
  38.         return;
  39.     }
  40.     traceprintf (fp, "%s", pax25 (tmp, hdr.source));
  41.     traceprintf (fp, "->%s", pax25 (tmp, hdr.dest));
  42.     if (hdr.ndigis > 0) {
  43.         traceprintf (fp, " v");
  44.         for (hp = hdr.digis[0]; hp < &hdr.digis[hdr.ndigis][0];
  45.              hp += AXALEN) {
  46.             /* Print digi string */
  47.             traceprintf (fp, " %s%s", pax25 (tmp, hp),
  48.                      (hp[ALEN] & REPEATED) ? "*" : "");
  49.         }
  50.     }
  51.     if ((control = PULLCHAR (bpp)) == -1)
  52.         return;
  53.  
  54.     traceprintf (fp, " ");
  55.     type = ftype (control);
  56.     traceprintf (fp, "%s", decode_the_type (type));
  57.     /* Dump poll/final bit */
  58.     if (control & PF) {
  59.         switch (hdr.cmdrsp) {
  60.             case LAPB_COMMAND:
  61.                 traceprintf (fp, "(P)");
  62.                 break;
  63.             case LAPB_RESPONSE:
  64.                 traceprintf (fp, "(F)");
  65.                 break;
  66.             default:
  67.                 traceprintf (fp, "(P/F)");
  68.                 break;
  69.         }
  70.     }
  71.     /* Dump sequence numbers */
  72.     if ((type & 0x3) != U)    /* I or S frame? */
  73.         traceprintf (fp, " NR=%d", (control >> 5) & 7);    /*lint !e702 */
  74.     if (type == I || type == UI) {
  75.         if (type == I)
  76.             traceprintf (fp, " NS=%d", (control >> 1) & 7);    /*lint !e702 */
  77.         /* Decode I field */
  78.         if ((pid = PULLCHAR (bpp)) != -1) {    /* Get pid */
  79.             if (pid == PID_SEGMENT) {
  80.                 unsegmented = 0;
  81.                 seg = PULLCHAR (bpp);
  82.                 traceprintf (fp, "%s remain %u", seg & SEG_FIRST ?
  83.                      " First seg;" : "", seg & SEG_REM);
  84.                 if (seg & SEG_FIRST)
  85.                     pid = PULLCHAR (bpp);
  86.             } else
  87.                 unsegmented = 1;
  88.  
  89.             switch (pid) {
  90.                 case PID_SEGMENT:
  91.                     traceprintf (fp, "\n");
  92.                     break;    /* Already displayed */
  93.                 case PID_ARP:
  94.                     traceprintf (fp, " pid=ARP (0x%x)\n", pid);
  95.                     arp_dump (fp, bpp);
  96.                     break;
  97.                 case PID_RARP:
  98.                     traceprintf (fp, " pid=RARP (0x%x)\n", pid);
  99.                     arp_dump (fp, bpp);
  100.                     break;
  101.                 case PID_NETROM:
  102.                     traceprintf (fp, " pid=NET/ROM (0x%x)\n", pid);
  103.                     /* Don't verify checksums unless unsegmented */
  104. #ifdef NETROM
  105.                     netrom_dump (fp, bpp, unsegmented);
  106. #endif
  107.                     break;
  108.                 case PID_IP:
  109.                     traceprintf (fp, " pid=IP (0x%x)\n", pid);
  110.                     /* Don't verify checksums unless unsegmented */
  111.                     ip_dump (fp, bpp, unsegmented);
  112.                     break;
  113.                 case PID_X25:
  114.                     traceprintf (fp, " pid=X.25 (0x%x)\n", pid);
  115.                     break;
  116.                 case PID_TEXNET:
  117.                     traceprintf (fp, " pid=TEXNET (0x%x)\n", pid);
  118.                     break;
  119.                 case PID_NO_L3:
  120.                     traceprintf (fp, " pid=Text (0x%x)\n", pid);
  121.                     break;
  122.                 default:
  123.                     traceprintf (fp, " pid=0x%x\n", pid);
  124.             }
  125.         }
  126.     } else if (type == FRMR && pullup (bpp, (unsigned char *) frmr, 3) == 3) {
  127.         traceprintf (fp, ": %s", decode_the_type (ftype (frmr[0])));
  128.         traceprintf (fp, " Vr = %d Vs = %d", (frmr[1] >> 5) & MMASK, (frmr[1] >> 1) & MMASK);    /*lint !e702 */
  129.         if (frmr[2] & W)
  130.             traceprintf (fp, " Invalid control field");
  131.         if (frmr[2] & X)
  132.             traceprintf (fp, " Illegal I-field");
  133.         if (frmr[2] & Y)
  134.             traceprintf (fp, " Too-long I-field");
  135.         if (frmr[2] & Z)
  136.             traceprintf (fp, " Invalid seq number");
  137.         traceprintf (fp, "\n");
  138.     } else
  139.         traceprintf (fp, "\n");
  140.  
  141. }
  142.  
  143.  
  144. static const char *
  145. decode_the_type (type)
  146. int16 type;
  147. {
  148.     switch (type) {
  149.         case I:        return "I";
  150.         case SABM:    return "SABM";
  151.         case DISC:    return "DISC";
  152.         case DM:    return "DM";
  153.         case UA:    return "UA";
  154.         case RR:    return "RR";
  155.         case RNR:    return "RNR";
  156.         case REJ:    return "REJ";
  157.         case FRMR:    return "FRMR";
  158.         case UI:    return "UI";
  159.         default:    return "[invalid]";
  160.     }
  161. }
  162.  
  163.  
  164. /* Return 1 if this packet is directed to us, 0 otherwise. Note that
  165.  * this checks only the ultimate destination, not the digipeater field
  166.  */
  167. int
  168. ax_forus (iface, bp)
  169. struct iface *iface;
  170. struct mbuf *bp;
  171. {
  172.     struct mbuf *bpp;
  173.     char dest[AXALEN];
  174.  
  175.     /* Duplicate the destination address */
  176.     if (dup_p (&bpp, bp, 0, AXALEN) != AXALEN) {
  177.         free_p (bpp);
  178.         return 0;
  179.     }
  180.     if (pullup (&bpp, (unsigned char *) dest, AXALEN) < AXALEN)
  181.         return 0;
  182.     if (addreq (dest, iface->hwaddr))
  183.         return 1;
  184.     else
  185.         return 0;
  186. }
  187.  
  188. #endif /* AX25 */
  189.